// -----------------------------------------------------------------------------
// -- Copyright (c) 2009 Xilinx, Inc.
// -- This design is confidential and proprietary of Xilinx, All Rights
// Reserved.
// -----------------------------------------------------------------------------
// -   ____  ____
// -  /   /\/   /
// - /___/  \  /   Vendor: Xilinx
// - \   \   \/    Version: 1.1
// -  \   \        Filename: SDR_4TO1_16CHAN_TOP.v
// -  /   /        
// - /___/   /\    Date Created: 07/14/2009 
// - \   \  /  \   
// -  \___\/\___\
// - 
// - Revision History:
// - Revision 1.1 06/28/2010 vasud
// - Updated MMCM Multiplier/Divider settings to match VCO frequency range
// -----------------------------------------------------------------------------
/*
--------------------------------------------------------------------------------
Description of module:

The SDR_4TO1_16CHAN_TOP module is the top level of the Hardware Test bench,
which serves as a test bench for the "interface under test", which is a 16
channel SFI LVDS interface.  This test bench includes pattern generators
and error detectors to test the integrity of the link and FIFO's to interface
to the receiver and transmitter.  Resets for the whole system are created in
this module.
--------------------------------------------------------------------------------
*/

`timescale 1ps/1ps
module SFI4_IF(
    RESET,

    SFI4_TXDATA_P,
    SFI4_TXDATA_N,
    SFI4_TXCLK_P,
    SFI4_TXCLK_N,
    
    SFI4_RXDATA_P,
    SFI4_RXDATA_N,
    SFI4_RXCLK_P,
    SFI4_RXCLK_N,
    
    INTERFACE_TXCLK_P,
    INTERFACE_TXCLK_N,
	OSC_200M,
    
    SFI4_RCLK,
    SFI4_RDATA,
    SFI4_TCLK,
    SFI4_TDATA,

    SFI_MANUAL_DELAY_INC,
    SFI_MANUAL_DELAY_DEC,
    SFI_TRAINING_DONE,
    SFI_IDELAY_READY
    );

input                 RESET;              //ALL RESETS CASCADE FROM THIS RESET

output[15:0]          SFI4_TXDATA_P;
output[15:0]          SFI4_TXDATA_N;
output                SFI4_TXCLK_P;
output                SFI4_TXCLK_N;

input[15:0]           SFI4_RXDATA_P;      //SOURCE SYNC DATA INPUT (P)
input[15:0]           SFI4_RXDATA_N;      //SOURCE SYNC DATA INPUT (N)
input                 SFI4_RXCLK_P;       //SOURCE SYNC CLOCK INPUT (P)
input                 SFI4_RXCLK_N;       //SOURCE SYNC CLOCK INPUT (N)

input                 INTERFACE_TXCLK_P;  //TX CLOCK SOURCE FROM CLKMOD2 (P)
input                 INTERFACE_TXCLK_N;  //TX CLOCK SOURCE FROM CLKMOD2 (N)
input				  OSC_200M;

output                SFI4_RCLK;
output[63:0]          SFI4_RDATA;
output                SFI4_TCLK;
input[63:0]           SFI4_TDATA;
//output[63:0]          SFI4_TDATA;

input                 SFI_MANUAL_DELAY_INC;
input                 SFI_MANUAL_DELAY_DEC;
output                SFI_TRAINING_DONE;
output                SFI_IDELAY_READY;


wire                  CLK200;

wire                  INTERFACE_TXCLK;
wire                  INTERFACE_TXCLK_BUFIO;

wire                  TXCLKDIV_BUFG;

wire[63:0]            DATA_FROM_ISERDES;    // output data from iserdes module
wire[63:0]			SFI4_TDATA_TX;


//IBUFGDS #(
//    .DIFF_TERM("TRUE"),
//    .IOSTANDARD("LVDS_25")
//     ) 
//    OSC_200_IN(
//    .O(OSC_200M), 
//    .I(OSC_200M_P), 
//    .IB(OSC_200M_N)
//    );

BUFG GLOBAL_CLK  (
    .O(CLK200), 
    .I(OSC_200M)
    );

//TRANSMITTER CLOCK INPUT
//IBUFDS #(
IBUFDS// #(                              // changed by DDV for semp request
//    .DIFF_TERM("TRUE"),
//    .IOSTANDARD("LVDS_25")    
//    .IOSTANDARD("LVPECL_25")           // changed by DDV for semp request
//    )
    TX_CLOCK_IN (
    .O(INTERFACE_TXCLK), 
    .I(INTERFACE_TXCLK_P), 
    .IB(INTERFACE_TXCLK_N)
    );

    
    
//CLOCK BUFFER FOR SERIAL SIDE CLOCK
BUFIO TX_CLK_BUFIO (
//    .CLR(1'b0),
//    .CE(1'b1),
    .O(INTERFACE_TXCLK_BUFIO), 
    .I(INTERFACE_TXCLK)
    );


//CLOCK BUFFER/DIVIDER FOR PARALLEL SIDE CLOCK
BUFR #(
  .BUFR_DIVIDE("4")
    ) 
   TX_CLK_BUFR (
    .O(TXCLKDIV), 
    .CE(1'b1), 
    .CLR(1'b0), 
    .I(INTERFACE_TXCLK)
    );


BUFG (
    .O(TXCLKDIV_BUFG), 
    .I(TXCLKDIV)
    );


//LVDS RECEIVER INTERFACE
SDR_4TO1_16CHAN_RX RX_IF(
    .DATA_RX_P              ( SFI4_RXDATA_P[15:0] ),
    .DATA_RX_N              ( SFI4_RXDATA_N[15:0] ),
    .CLOCK_RX_P             ( SFI4_RXCLK_P ),
    .CLOCK_RX_N             ( SFI4_RXCLK_N ),
    .INC_PAD                ( SFI_MANUAL_DELAY_INC ),
    .DEC_PAD                ( SFI_MANUAL_DELAY_DEC ),
    .DATA_FROM_ISERDES      ( DATA_FROM_ISERDES[63:0] ),   // DATA TO SFI4 INTERNAL INTERFACE
    .RESET                  ( RESET ),
    .IDLY_RESET             ( 1'b0 ),
    .IDELAYCTRL_RESET       ( RESET ),
    .CLK200                 ( CLK200 ),
    .TAP_00                 ( ),
    .TAP_01                 ( ),
    .TAP_02                 ( ),
    .TAP_03                 ( ),
    .TAP_04                 ( ),
    .TAP_05                 ( ),
    .TAP_06                 ( ),
    .TAP_07                 ( ),
    .TAP_08                 ( ),
    .TAP_09                 ( ),
    .TAP_10                 ( ),
    .TAP_11                 ( ),
    .TAP_12                 ( ),
    .TAP_13                 ( ),
    .TAP_14                 ( ),
    .TAP_15                 ( ),
    .TAP_CLK                ( ),
    .TRAINING_DONE          (SFI_TRAINING_DONE),
    .RXCLK                  ( ),
    .RXCLKDIV               (RXCLKDIV),
    .IDELAY_READY           (SFI_IDELAY_READY)
    );

  // 16-bit sequence invert, iserdes receive bit sequence is 15:0/31:16/47:32/63:48
  assign  SFI4_RDATA[63:48] =DATA_FROM_ISERDES[15:0];
  assign  SFI4_RDATA[47:32] =DATA_FROM_ISERDES[31:16];
  assign  SFI4_RDATA[31:16] =DATA_FROM_ISERDES[47:32];
  assign  SFI4_RDATA[15:0]  =DATA_FROM_ISERDES[63:48];

//assign  SFI4_RDATA[63:48] =!DATA_FROM_ISERDES[63:48];
//assign  SFI4_RDATA[47:32] =!DATA_FROM_ISERDES[47:32];
//assign  SFI4_RDATA[31:16] =!DATA_FROM_ISERDES[31:16];
//assign  SFI4_RDATA[15:0]  =!DATA_FROM_ISERDES[15:0];



//LVDS TRANSMITTER INTERFACE
SDR_4TO1_16CHAN_TX          TX_IF(
    .DATA_TX_P              ( SFI4_TXDATA_P[15:0] ),
    .DATA_TX_N              ( SFI4_TXDATA_N[15:0] ),
    .CLOCK_TX_P             ( SFI4_TXCLK_P ),
    .CLOCK_TX_N             ( SFI4_TXCLK_N ),
    .TXCLK                  ( INTERFACE_TXCLK_BUFIO ),
    .TXCLKDIV               ( TXCLKDIV ),
//  .TXCLKDIV               ( TXCLKDIV_G ),
    .DATA_TO_OSERDES        ( {SFI4_TDATA_TX[15:0], SFI4_TDATA_TX[31:16], SFI4_TDATA_TX[47:32],SFI4_TDATA_TX[63:48]} ),
    .RESET                  ( RESET )
    );
   
// assign SFI4_TCLK    =TXCLKDIV_BUFG;
   assign SFI4_TCLK    =TXCLKDIV;
   assign SFI4_RCLK    =RXCLKDIV;
// assign SFI4_RCLK    =RXCLKDIV;


assign SFI4_TDATA_TX[00] = SFI4_TDATA[00];
assign SFI4_TDATA_TX[01] = SFI4_TDATA[01];
assign SFI4_TDATA_TX[02] = SFI4_TDATA[02];
assign SFI4_TDATA_TX[03] = SFI4_TDATA[03];
assign SFI4_TDATA_TX[04] = SFI4_TDATA[04];
assign SFI4_TDATA_TX[05] = SFI4_TDATA[05];
assign SFI4_TDATA_TX[06] = SFI4_TDATA[06];
assign SFI4_TDATA_TX[07] = SFI4_TDATA[07];
assign SFI4_TDATA_TX[08] = SFI4_TDATA[08];
assign SFI4_TDATA_TX[09] = SFI4_TDATA[09];
assign SFI4_TDATA_TX[10] = SFI4_TDATA[10];
assign SFI4_TDATA_TX[11] = SFI4_TDATA[11];
assign SFI4_TDATA_TX[12] = SFI4_TDATA[12];
assign SFI4_TDATA_TX[13] = SFI4_TDATA[13];
assign SFI4_TDATA_TX[14] = SFI4_TDATA[14];
assign SFI4_TDATA_TX[15] = SFI4_TDATA[15];
assign SFI4_TDATA_TX[16] = SFI4_TDATA[16];
assign SFI4_TDATA_TX[17] = SFI4_TDATA[17];
assign SFI4_TDATA_TX[18] = SFI4_TDATA[18];
assign SFI4_TDATA_TX[19] = SFI4_TDATA[19];
assign SFI4_TDATA_TX[20] = SFI4_TDATA[20];
assign SFI4_TDATA_TX[21] = SFI4_TDATA[21];
assign SFI4_TDATA_TX[22] = SFI4_TDATA[22];
assign SFI4_TDATA_TX[23] = SFI4_TDATA[23];
assign SFI4_TDATA_TX[24] = SFI4_TDATA[24];
assign SFI4_TDATA_TX[25] = SFI4_TDATA[25];
assign SFI4_TDATA_TX[26] = SFI4_TDATA[26];
assign SFI4_TDATA_TX[27] = SFI4_TDATA[27];
assign SFI4_TDATA_TX[28] = SFI4_TDATA[28];
assign SFI4_TDATA_TX[29] = SFI4_TDATA[29];
assign SFI4_TDATA_TX[30] = SFI4_TDATA[30];
assign SFI4_TDATA_TX[31] = SFI4_TDATA[31];
assign SFI4_TDATA_TX[32] = SFI4_TDATA[32];
assign SFI4_TDATA_TX[33] = SFI4_TDATA[33];
assign SFI4_TDATA_TX[34] = SFI4_TDATA[34];
assign SFI4_TDATA_TX[35] = SFI4_TDATA[35];
assign SFI4_TDATA_TX[36] = SFI4_TDATA[36];
assign SFI4_TDATA_TX[37] = SFI4_TDATA[37];
assign SFI4_TDATA_TX[38] = SFI4_TDATA[38];
assign SFI4_TDATA_TX[39] = SFI4_TDATA[39];
assign SFI4_TDATA_TX[40] = SFI4_TDATA[40];
assign SFI4_TDATA_TX[41] = SFI4_TDATA[41];
assign SFI4_TDATA_TX[42] = SFI4_TDATA[42];
assign SFI4_TDATA_TX[43] = SFI4_TDATA[43];
assign SFI4_TDATA_TX[44] = SFI4_TDATA[44];
assign SFI4_TDATA_TX[45] = SFI4_TDATA[45];
assign SFI4_TDATA_TX[46] = SFI4_TDATA[46];
assign SFI4_TDATA_TX[47] = SFI4_TDATA[47];
assign SFI4_TDATA_TX[48] = SFI4_TDATA[48];
assign SFI4_TDATA_TX[49] = SFI4_TDATA[49];
assign SFI4_TDATA_TX[50] = SFI4_TDATA[50];
assign SFI4_TDATA_TX[51] = SFI4_TDATA[51];
assign SFI4_TDATA_TX[52] = SFI4_TDATA[52];
assign SFI4_TDATA_TX[53] = SFI4_TDATA[53];
assign SFI4_TDATA_TX[54] = SFI4_TDATA[54];
assign SFI4_TDATA_TX[55] = SFI4_TDATA[55];
assign SFI4_TDATA_TX[56] = SFI4_TDATA[56];
assign SFI4_TDATA_TX[57] = SFI4_TDATA[57];
assign SFI4_TDATA_TX[58] = SFI4_TDATA[58];
assign SFI4_TDATA_TX[59] = SFI4_TDATA[59];
assign SFI4_TDATA_TX[60] = SFI4_TDATA[60];
assign SFI4_TDATA_TX[61] = SFI4_TDATA[61];
assign SFI4_TDATA_TX[62] = SFI4_TDATA[62];
assign SFI4_TDATA_TX[63] = SFI4_TDATA[63];


   
   
   
   
endmodule